{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'\\nbacktest\\n\\nGives several examples of backtesting simple trading strategies, using Backtest (a lower level class)\\n\\n'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "__author__ = 'saeedamen'  # Saeed Amen\n",
    "\n",
    "#\n",
    "# Copyright 2016 Cuemacro\n",
    "#\n",
    "# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the\n",
    "# License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0\n",
    "#\n",
    "# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an\n",
    "# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
    "#\n",
    "# See the License for the specific language governing permissions and limitations under the License.\n",
    "#\n",
    "\n",
    "\"\"\"\n",
    "backtest\n",
    "\n",
    "Gives several examples of backtesting simple trading strategies, using Backtest (a lower level class)\n",
    "\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# for backtest and loading data\n",
    "from finmarketpy.backtest import BacktestRequest, Backtest\n",
    "from findatapy.market import Market, MarketDataRequest, MarketDataGenerator\n",
    "from findatapy.util.fxconv import FXConv\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# for logging\n",
    "from findatapy.util.loggermanager import LoggerManager\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# for signal generation\n",
    "from finmarketpy.economics import TechIndicator, TechParams\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# for plotting\n",
    "from chartpy import Chart, Style\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# housekeeping\n",
    "logger = LoggerManager().getLogger(__name__)\n",
    "\n",
    "import datetime\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2019-11-02 15:17:31,641 - __main__ - INFO - Loading asset data...\n",
      "2019-11-02 15:17:32,265 - findatapy.market.datavendorweb - INFO - Request Quandl data\n",
      "2019-11-02 15:17:32,266 - findatapy.market.datavendorweb - INFO - Request Quandl data2019-11-02 15:17:32,270 - findatapy.market.datavendorweb - INFO - Request Quandl data\n",
      "\n",
      "2019-11-02 15:17:32,270 - findatapy.market.datavendorweb - INFO - Request Quandl data\n",
      "2019-11-02 15:17:35,867 - findatapy.market.datavendorweb - INFO - Completed request from Quandl for ['EURUSD.close']\n",
      "2019-11-02 15:17:36,000 - findatapy.market.datavendorweb - INFO - Request Quandl data\n",
      "2019-11-02 15:17:37,908 - findatapy.market.datavendorweb - INFO - Completed request from Quandl for ['GBPUSD.close']\n",
      "2019-11-02 15:17:38,078 - findatapy.market.datavendorweb - INFO - Request Quandl data\n",
      "2019-11-02 15:17:38,120 - findatapy.market.datavendorweb - INFO - Completed request from Quandl for ['USDJPY.close']\n",
      "2019-11-02 15:17:38,481 - findatapy.market.datavendorweb - INFO - Request Quandl data\n",
      "2019-11-02 15:17:40,606 - findatapy.market.datavendorweb - INFO - Completed request from Quandl for ['AUDUSD.close']\n",
      "2019-11-02 15:17:40,743 - findatapy.market.datavendorweb - INFO - Request Quandl data\n",
      "2019-11-02 15:17:41,608 - findatapy.market.datavendorweb - INFO - Completed request from Quandl for ['USDCAD.close']\n",
      "2019-11-02 15:17:41,696 - findatapy.market.datavendorweb - INFO - Request Quandl data\n",
      "2019-11-02 15:17:42,674 - findatapy.market.datavendorweb - INFO - Completed request from Quandl for ['NZDUSD.close']\n"
     ]
    }
   ],
   "source": [
    "# pick USD crosses in G10 FX\n",
    "# note: we are calculating returns from spot (it is much better to use to total return\n",
    "# indices for FX, which include carry)\n",
    "logger.info(\"Loading asset data...\")\n",
    "\n",
    "tickers = ['EURUSD', 'USDJPY', 'GBPUSD', 'AUDUSD', 'USDCAD',\n",
    "           'NZDUSD', 'USDCHF', 'USDNOK', 'USDSEK']\n",
    "\n",
    "vendor_tickers = ['FRED/DEXUSEU', 'FRED/DEXJPUS', 'FRED/DEXUSUK', 'FRED/DEXUSAL', 'FRED/DEXCAUS',\n",
    "                  'FRED/DEXUSNZ', 'FRED/DEXSZUS', 'FRED/DEXNOUS', 'FRED/DEXSDUS']\n",
    "\n",
    "md_request = MarketDataRequest(\n",
    "    start_date=\"01 Jan 1989\",  # start date\n",
    "    finish_date=datetime.date.today(),  # finish date\n",
    "    freq='daily',  # daily data\n",
    "    data_source='quandl',  # use Quandl as data source\n",
    "    tickers=tickers,  # ticker (findatapy)\n",
    "    fields=['close'],  # which fields to download\n",
    "    vendor_tickers=vendor_tickers,  # ticker (Quandl)\n",
    "    vendor_fields=['close'],  # which Bloomberg fields to download\n",
    "    cache_algo='internet_load_return')  # how to return data\n",
    "\n",
    "market = Market(market_data_generator=MarketDataGenerator())\n",
    "\n",
    "asset_df = market.fetch_market(md_request)\n",
    "spot_df = asset_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "backtest = Backtest()\n",
    "br = BacktestRequest()\n",
    "fxconv = FXConv()\n",
    "\n",
    "# get all asset data\n",
    "br.start_date = \"02 Jan 1990\"\n",
    "br.finish_date = datetime.datetime.utcnow()\n",
    "br.spot_tc_bp = 0  # 2.5 bps bid/ask spread\n",
    "br.ann_factor = 252\n",
    "\n",
    "# have vol target for each signal\n",
    "br.signal_vol_adjust = True\n",
    "br.signal_vol_target = 0.05\n",
    "br.signal_vol_max_leverage = 3\n",
    "br.signal_vol_periods = 60\n",
    "br.signal_vol_obs_in_year = 252\n",
    "br.signal_vol_rebalance_freq = 'BM'\n",
    "br.signal_vol_resample_freq = None\n",
    "\n",
    "tech_params = TechParams();\n",
    "tech_params.bb_period = 200;\n",
    "tech_params.bb_mult = 0.5 ;\n",
    "indicator = 'BB'\n",
    "\n",
    "logger.info(\"Running backtest...\")\n",
    "\n",
    "# use technical indicator to create signals\n",
    "# (we could obviously create whatever function we wanted for generating the signal dataframe)\n",
    "tech_ind = TechIndicator()\n",
    "tech_ind.create_tech_ind(spot_df, indicator, tech_params);\n",
    "signal_df = tech_ind.get_signal()\n",
    "\n",
    "contract_value_df = None\n",
    "\n",
    "# use the same data for generating signals\n",
    "backtest.calculate_trading_PnL(br, asset_df, signal_df, contract_value_df, run_in_parallel=False)\n",
    "port = backtest.portfolio_cum()\n",
    "port.columns = [indicator + ' = ' + str(tech_params.sma_period) + ' ' + str(backtest.portfolio_pnl_desc()[0])]\n",
    "signals = backtest.portfolio_signal()\n",
    "\n",
    "# print the last positions (we could also save as CSV etc.)\n",
    "print(signals.tail(1))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "style = Style()\n",
    "style.title = \"FX trend strategy\"\n",
    "style.source = 'Quandl'\n",
    "style.scale_factor = 1\n",
    "style.file_output = 'fx-trend-example.png'\n",
    "\n",
    "Chart().plot(port, style=style)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  },
  "pycharm": {
   "stem_cell": {
    "cell_type": "raw",
    "source": [],
    "metadata": {
     "collapsed": false
    }
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}